<?php
namespace app\api\controller\task;

use app\api\controller\Api;
use app\common\task\model\Task as TaskUpload;
use think\db\exception\DbException;
use util\Format;

class Upload extends Api
{
    public function index()
    {
        $post = $this->request->post();

        $where = [];
        if (isset($post['keyword']) && !empty($post['keywords'])) $where[] = ['title', 'like', "%{$post['keywords']}%"];

        $model = new TaskUpload();
        list($cfg) = Format::pagination($post);
        $pg = $model->where($where)->order('id')->paginate($cfg);
        $rows = $pg->getCollection();

        // 返回接口数据
        $result['list'] = $rows;
        $result['pagination'] = Format::pgResult($pg);

        return success($result, '获取数据成功');
    }
    
    public function delete()
    {
        $post = $this->request->post();
        // 验证提交
        if (empty($post['id'])) return error([], '请选择要删除的设备');

        $model = new TaskUpload();
        $row = $model->where('id', $post['id'])->find();
        if (empty($row)) return error([], '设备已不存在');
        // 非软删除，直接删除
        $rs = $row->delete(true);

        if ($rs) {
            return success([], '删除成功');
        } else {
            return error([], '删除失败');
        }
    }

    public function create()
    {
        $post = $this->request->post();
        $dir = !empty($post['field']) ? $post['field'] : 'file';
        // 获取上传配置
        $systemConfigLogic = new \app\common\config\logic\ConfigSystem();
        $uploadConfig = $systemConfigLogic->getConfigItem("upload");

        $file = $this->request->file('file');
        if (empty($file)) return error([], '请选择要上传的文件');

        try {
            $rules = [
                "file" => ["fileSize:{$uploadConfig['size']}", "fileExt:{$uploadConfig['ext']}"],
            ];
            $messages = [
                "file.fileSize" => '文件不超过',
                "file.fileExt"  => '不支持的文件格式'
            ];
            $validateLogic = validate($rules, $messages);
            $checkRs = $validateLogic->check(['file' => $file]);
            if (!$checkRs) {
                return error([], $validateLogic->getError());
            }

            $env = getenv("SERVER_ENV");
            $config = config('filesystem.disks');
            if ($env == 'test') {
                $filePath = \think\facade\Filesystem::disk("public")->putFile($dir, $file);
                $hash = md5_file($config['public']['root'] . '/' . $filePath);
                $saveName = $config['public']['url'] . str_ireplace('\\', '/', $filePath);
            } else {
                $filePath = \think\facade\Filesystem::disk("image")->putFile($dir, $file);
                $hash = md5_file($config['image']['root'] . '/' . $filePath);
                $saveName = $config['image']['url'] . str_ireplace('\\', '/', $filePath);
            }

            if ($saveName) {

                $data['path'] = $this->request->domain() . $saveName;
                $data['file_name'] = $file->getOriginalName();
                $data['file_path'] = $saveName;
                // 读取文件行数
                $file_content = file_get_contents($config['public']['root'] . '/' . $filePath);
                // 删除空行
                $tasks = array_filter(explode("\n", $file_content), function($v) {
                    return $v !== '';
                });
                $data['totals'] = count($tasks);
                $data['hash'] = $hash;
        
                // 保存数据库
                $model = new TaskUpload();
                try {
                    $model->save($data);
                } catch (DbException $e) {
                    return error([], $e->getMessage());
                }

                return success($data, '上传成功');
            } else {
                return error([], '上传失败');
            }
        } catch (ValidateException $e) {
            return error([], $e->getMessage());
        }
    }

    public function assign()
    {
        $post = $this->request->post();
        if (empty($post['id'])) return error([], '请选择要分配的任务');

        $model = new TaskUpload();
        $row = $model->where('id', $post['id'])->find();
        if (empty($row)) return error([], '任务不存在');

        if ($row->is_assign == 1) return error([], '任务已分配');

        // $row['file_path'],读取文件行数
        $file_content = file_get_contents("./".$row->file_path);
        $tasks = explode("\n", $file_content);

        // 删除空行
        $tasks = array_filter($tasks, function($v) {
            return $v !== '';
        });


        // 获取所有在使用的设备,id,uuid
        $deviceModel = new \app\common\task\model\Device();
        $deviceList = $deviceModel->field('id,uuid')->where('status', 1)->select();
        if (empty($deviceList)) {
            return error([], '没有可用的设备');
        }

        // 将任务平均分配到设备上
        $deviceCount = count($deviceList);
        $taskCount = count($tasks);
        $taskPerDevice = ceil($taskCount / $deviceCount);
        
        foreach ($deviceList as $key=>$device) {
            
            // 获取设备的任务数
            $start = $key * $taskPerDevice;
            $end = $start + $taskPerDevice;
            if ($end > $taskCount) {
                $end = $taskCount;
            }
            // 如果$key 是最后一个设备，则将剩余的任务分配到最后一个设备上
            if ($key == $deviceCount - 1) {
                $end = $taskCount;
            }
            $deviceTasks = array_slice($tasks, $start, $end);
            
            $batchData = [];
            foreach ($deviceTasks as $task) {
                // 获取$task url 中的主机名
                $url = parse_url($task);
                $host = $url['host'];
                $batchData[] = [
                    'task_id' => $row->id,
                    'device_id' => $device->id,
                    'device_uuid' => $device->uuid,
                    'url' => $task,
                    'category' => $url['host']
                ];
            }

            $taskBoomModel = new \app\common\task\model\TaskBoom();
            $taskBoomModel->insertAll($batchData);
        }

        // 设置已分配is_assign
        $row->is_assign = 1;
        $row->save();
        return success([], '分配成功');
    }
}